#pragma once

#define _USE_MATH_DEFINES
#include "math.h"
#include "memory.h"

/**
 * <p>Title: CVector3D</p>
 * <p>Description: CVector3D class represents 3D vector</p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: CIANT</p>
 * @author not attributable
 * @version 1.0
 */

/** CVector3D class represents 3D vector.
*
*/
class CVector3D {
public:
  
  /// x y z components
  float v[3];

  /// Construct a zero vector [0 0 0].
  CVector3D() {
    memset(v, 0, 3*sizeof(float));
  }

  /** Construct a vector given its 3 [x y z] components.
  * @param x x component
  * @param y y component
  * @param z z component
  */
  CVector3D(float x, float y, float z) {
    v[0] = x; v[1] = y; v[2] = z;
  }

  /** Construct a vector given its 3 [x y z] components.
  * @param vec [x y z] components
  */
  CVector3D(float vec[]) {
    memcpy(v, vec, 3*sizeof(float));
  }

  /** Set components of the vector.
  * @param x x component
  * @param y y component
  * @param z z component
  */
  void setVector(float x, float y, float z) {
    v[0] = x; v[1] = y; v[2] = z;
  }

  /// Compute magnitude of the vector.
  float getMagnitude() {
    return (float) sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
  }

  /// Normalize the vector.
  void normalize() {
    float m = getMagnitude();
    v[0] /= m; v[1] /= m; v[2] /= m;
  }

  /** Compute linear interpolation between two vectors.
  * @param v1 first vector
  * @param v2 second vector
  * @param t interpolation parametr (0..1)
  * @return interpolated vector
  */
  static CVector3D interp(CVector3D v1, CVector3D v2, float t);

  /** Compute difference between two vectors.
  * @param v1 first vector
  * @param v2 second vector
  * @return magnitude of (v1-v2)
  */
  static float diff(CVector3D v1, CVector3D v2) {
    return sqrt(sqr(v1.v[0]-v2.v[0]) + sqr(v1.v[1]-v2.v[1]) + sqr(v1.v[2]-v2.v[2]));
  }

protected:

  /// float sqr
  static float sqr(float a) {
    return a * a;
  }

};